from dryfire.model.moaModel import MOAModel
from dryfire.model.shapeModel import OutdoorShapeModel, DryFireShapeModel
from dryfire.model.spaceModel import OutdoorSpaceModel, DryFireSpaceModel
from dryfire.model.targetModel import DryFireTargetPartNode, moa_to_inches

class HorizontalBarsMOAModel(MOAModel):

    moas = (9, 8, 7, 6, 5, 4, 3, 2)
    bar_width_moa = 3

    def __init__(self):
        MOAModel.__init__(self, "Horizontal MOA Bars")
        self._build()
        self._set_sizer()

    # private methods

    def _build(self):
        # build from bottom to top
        moas = list(HorizontalBarsMOAModel.moas)
        moa = moas.pop(0)
        part_node = self._build_bar(moa)
        self._parts_tree = part_node
        self._parts_list.append(part_node)
        last_part_node = part_node
        part_node = self._build_space()
        last_part_node.node_up = part_node
        part_node.node_down = last_part_node
        self._parts_list.append(part_node)
        last_part_node = part_node
        for i in moas:
            # moa
            part_node = self._build_bar(i)
            last_part_node.node_up = part_node
            part_node.node_down = last_part_node
            self._parts_list.append(part_node)
            last_part_node = part_node
            # space
            part_node = self._build_space()
            last_part_node.node_up = part_node
            part_node.node_down = last_part_node
            self._parts_list.append(part_node)
            last_part_node = part_node
        # rebuild the description
        desc_list = []
        desc_list.append(self._description)
        rmoas = reversed(HorizontalBarsMOAModel.moas)
        moa_list = [str(i) for i in rmoas]
        line = "This is not a target. This is {0} horizontal bars that you can"\
               " use to check your scope."
        desc_list.append(line.format(len(moa_list)))
        moatext = ", ".join(moa_list)
        line = "The bars are from top to bottom, {0} MOA."
        desc_list.append(line.format(moatext))
        line = "Each bar is {0} MOA high and the bars are {0} MOA apart."
        desc_list.append(line.format(HorizontalBarsMOAModel.bar_width_moa))
        self._description = '\n'.join(desc_list)

    def _build_bar(self, w):
        # add the head
        h = HorizontalBarsMOAModel.bar_width_moa
        desc_text = '{0} MOA wide bar.'
        desc = desc_text.format(w)
        o_model = OutdoorShapeModel(moa_to_inches(w), moa_to_inches(h),
                                    OutdoorShapeModel.shape_rectangle,
                                    self._outdoor_distance_yards,
                                    desc)
        d_model = DryFireShapeModel(o_model, self._indoor_distance_feet)
        part_node = DryFireTargetPartNode(d_model)
        return part_node

    def _build_space(self):
        # add the head
        w = 0
        h = HorizontalBarsMOAModel.bar_width_moa
        o_model = OutdoorSpaceModel(w, moa_to_inches(h),
                                    self._outdoor_distance_yards,
                                    '')
        d_model = DryFireSpaceModel(o_model, self._indoor_distance_feet)
        part_node = DryFireTargetPartNode(d_model)
        return part_node



class VerticalBarsMOAModel(MOAModel):

    moas = (9, 8, 7, 6, 5, 4, 3, 2)
    bar_width_moa = 3

    def __init__(self):
        MOAModel.__init__(self, "Vertital MOA Bars")
        self._build()
        self._set_sizer()

    # private methods

    def _build(self):
        # build from bottom to top
        moas = list(VerticalBarsMOAModel.moas)
        moa = moas.pop(0)
        part_node = self._build_bar(moa)
        self._parts_tree = part_node
        self._parts_list.append(part_node)
        last_part_node = part_node
        part_node = self._build_space()
        last_part_node.node_right = part_node
        part_node.node_left = last_part_node
        self._parts_list.append(part_node)
        last_part_node = part_node
        for i in moas:
            # moa
            part_node = self._build_bar(i)
            last_part_node.node_right = part_node
            part_node.node_left = last_part_node
            self._parts_list.append(part_node)
            last_part_node = part_node
            # space
            part_node = self._build_space()
            last_part_node.node_right = part_node
            part_node.node_left = last_part_node
            self._parts_list.append(part_node)
            last_part_node = part_node
        # rebuild the description
        desc_list = []
        desc_list.append(self._description)
        moa_list = [str(i) for i in VerticalBarsMOAModel.moas]
        line = "This is not a target. This is {0} vertical bars that you can"\
               " use to check your scope."
        desc_list.append(line.format(len(moa_list)))
        moatext = ", ".join(moa_list)
        line = "The bars are from left to right, {0} MOA."
        desc_list.append(line.format(moatext))
        line = "Each bar is {0} MOA wide and the bars are {0} MOA apart."
        desc_list.append(line.format(VerticalBarsMOAModel.bar_width_moa))
        self._description = '\n'.join(desc_list)

    def _build_bar(self, h):
        # add the head
        w = VerticalBarsMOAModel.bar_width_moa
        desc_text = '{0} MOA high bar.'
        desc = desc_text.format(h)
        o_model = OutdoorShapeModel(moa_to_inches(w), moa_to_inches(h),
                                    OutdoorShapeModel.shape_rectangle,
                                    self._outdoor_distance_yards,
                                    desc)
        d_model = DryFireShapeModel(o_model, self._indoor_distance_feet)
        part_node = DryFireTargetPartNode(d_model)
        return part_node

    def _build_space(self):
        # add the head
        h = 0
        w = VerticalBarsMOAModel.bar_width_moa
        o_model = OutdoorSpaceModel(moa_to_inches(w), h,
                                    self._outdoor_distance_yards,
                                    '')
        d_model = DryFireSpaceModel(o_model, self._indoor_distance_feet)
        part_node = DryFireTargetPartNode(d_model)
        return part_node
